package com.base.pig.controller;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.pig.dto.*;
import com.base.pig.entity.AlarmSensor;
import com.base.pig.entity.AlarmSetting;

import com.base.pig.entity.SensorCheckAlarm;
import com.base.pig.poi.Column;
import com.base.pig.poi.ExcelUtils;
import com.base.pig.poi.ExportRules;
import com.base.pig.service.AlarmSensorService;
import com.base.pig.service.AlarmSettingService;
import com.base.pig.service.SensorCheckAlarmService;
import com.base.pig.service.SmregisterService;
import com.base.pig.util.HttpUtils;
import com.base.pig.util.R;

import com.base.pig.util.WebSocketServer;
import com.base.pig.vo.AlarmListVo;
import com.base.pig.vo.AlarmOnTimeVo;
import com.base.pig.vo.SensorListVo;
import com.base.pig.vo.StatisticResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  报警功能controller
 * </p>
 *
 * @author wangzhx
 * @since 2022-04-12
 */
@RestController
@Api(value = "AlarmController", tags = "报警管理")
@RequestMapping("/AlarmController")
public class AlarmController {

    @Value("")
    private String cleanAlarmSettingUrl;

    @Autowired
    public AlarmSettingService alarmSettingService;
    @Autowired
    public AlarmSensorService alarmSensorService;
    @Autowired
    public SensorCheckAlarmService sensorCheckAlarmService;
    @Autowired
    public SmregisterService smregisterService;

    @Autowired
    public WebSocketServer webSocketServer;

    @ApiOperation(value = "查看平台地址")
    @PostMapping("/test")
    public R test(){
        return R.ok(cleanAlarmSettingUrl,"获取成功");
    }

    @ApiOperation(value = "报警统计数据")
    @PostMapping("/statistic")
    public R statistic(){
        TableDto tableDto = new TableDto();
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        tableDto.setDeviceTableName(deviceTableName);
        tableDto.setMonitorTableName(monitorTableName);
        StatisticResultVo vo =  sensorCheckAlarmService.deviceStastistic(tableDto);
        return R.ok(vo,"");
    }

    @ApiOperation(value = "新增报警设置")
    @PostMapping("/save")
    public R save(@RequestBody AlarmSetting alarmSetting){
        long count = alarmSettingService.count(Wrappers.<AlarmSetting>query().lambda().eq(AlarmSetting::getName,alarmSetting.getName()));
        if(count == 0) {
            Date date = new Date();
            alarmSetting.setTime(date);
            boolean b = alarmSettingService.save(alarmSetting);
            if (b){
                return R.ok(b,"添加成功");
            }
            return R.failed(null,"添加失败");
        }
        return R.failed(null,"报警设置名称重复");
    }

    @ApiOperation(value = "根据id删除报警设置")
    @PostMapping("/delete")
    public R delete(@RequestBody IdDto idDto){
        alarmSettingService.removeById(idDto.getId());
        return R.ok(null,"删除成功");
    }

    /**
     * @param alarmSettingListDto: 请求参数集合 : {
     *             personid : 巡检人员id
     *             status : 状态
     *             current : 分页数,默认1
     *             size: 每页记录数
     *             }
     * @return R
     * @Title 分页获取报警设置列表
     * @Description
     * @author wzx
     * @date 2022/3/21
     */
    @ApiOperation(value = "分页获取报警设置列表")
    @PostMapping("/alarmSettingList")
    public R list(@RequestBody AlarmSettingListDto alarmSettingListDto){
        QueryWrapper alarmSettingWrapper = new QueryWrapper();
        // 全量查询
        if(StrUtil.isNotBlank(alarmSettingListDto.getName())){
            alarmSettingWrapper.like("name",alarmSettingListDto.getName());
        }
        if(StrUtil.isNotBlank(alarmSettingListDto.getDeleted())){
            alarmSettingWrapper.eq("deleted",alarmSettingListDto.getDeleted());
        }
        alarmSettingWrapper.orderByDesc("time");
        IPage<AlarmSetting> page = alarmSettingService.page(
                new Page<>(alarmSettingListDto.getCurrent(), alarmSettingListDto.getSize()),
                alarmSettingWrapper);
        return R.ok(page,"分页查询信息成功");
    }

    @ApiOperation(value = "根据id修改报警设置")
    @PostMapping("/alarmSettingUpdate")
    public R update(@RequestBody AlarmSetting alarmSetting){
        if(alarmSetting.getAlarmId() != null){
            long count = alarmSettingService.count(Wrappers.<AlarmSetting>query().lambda().eq(AlarmSetting::getName,alarmSetting.getName()).ne(AlarmSetting::getAlarmId,alarmSetting.getAlarmId()));
            if(count == 0) {
                Date date = new Date();
                alarmSetting.setTime(date);
                return R.ok( alarmSettingService.updateById(alarmSetting),"修改成功");
            }
            return R.failed(null,"报警设置名称重复");
        }
        return R.failed(null,"id不能为空");
    }

 /*   @ApiOperation(value = "获取没有绑定该报警设置编号的传感器列表")
    @PostMapping("/noBindSensorList")
    public R noBindSensorList(@RequestBody SensorListDto sensorListDto){
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        sensorListDto.setDeviceTableName(deviceTableName);
        sensorListDto.setMonitorTableName(monitorTableName);
        IPage<SensorListVo> page = alarmSettingService.noBindSensorList(sensorListDto);
        return R.ok(page,"获取成功");
    }

    @ApiOperation(value = "获取绑定该报警设置编号的传感器列表")
    @PostMapping("/bindSensorList")
    public R bindSensorList(@RequestBody SensorListDto sensorListDto){
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        sensorListDto.setDeviceTableName(deviceTableName);
        sensorListDto.setMonitorTableName(monitorTableName);
        IPage<SensorListVo> page = alarmSettingService.bindSensorList(sensorListDto);
        return R.ok(page,"获取成功");
    }*/

    @ApiOperation(value = "获取所有传感器列表")
    @PostMapping("/allSensorList")
    public R allSensorList(){
        TableDto tableDto = new TableDto();
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        tableDto.setDeviceTableName(deviceTableName);
        tableDto.setMonitorTableName(monitorTableName);
        List<SensorListVo> list = alarmSettingService.allSensorList(tableDto);
        list.stream().map(SensorListVo -> {
            if(SensorListVo.getSensorId() != null){
                SensorListVo.setSensorId(SensorListVo.getDeviceCode()+"/"+SensorListVo.getSensorId()+"/"+SensorListVo.getSensorCode());
            }else{
                SensorListVo.setSensorId(SensorListVo.getDeviceCode()+"/"+SensorListVo.getSensorCode());
            }
            return SensorListVo;
        }).collect(Collectors.toList());
        return R.ok(list,"获取成功");
    }

    @ApiOperation(value = "获取绑定传感器id数组")
    @PostMapping("/bindSensorArray")
    public R bindSensorArray(@RequestBody IdDto idDto){
        String[] list = alarmSettingService.bindSensorArray(idDto);
        return R.ok(list,"获取成功");
    }


    @ApiOperation(value = "报警设置绑定传感器")
    @PostMapping("/alarmSettingBindSensor")
    public R alarmSettingBindSensor(@RequestBody AlarmSettingBindDto alarmSettingBindDto){
        if(alarmSettingBindDto.getAlarmSettingId() != null){
            String alarmSettingId = alarmSettingBindDto.getAlarmSettingId();
            long count = alarmSettingService.count(Wrappers.<AlarmSetting>query().lambda().eq(AlarmSetting::getAlarmId,alarmSettingId));
            if(count != 0) {
                String[] ids = alarmSettingBindDto.getSensorIds();
                for(String id : ids){
                    List<AlarmSensor> list = alarmSensorService.list(Wrappers.<AlarmSensor>query().lambda().eq(AlarmSensor::getSensorid,id));
                    list.stream().forEach(alarmSensor -> {
                        alarmSensorService.removeById(alarmSensor.getId());
                    });
                    AlarmSensor alarmSensor = new AlarmSensor();
                    alarmSensor.setAlarmsetingid(alarmSettingId);
                    alarmSensor.setSensorid(id);
                    alarmSensorService.save(alarmSensor);
                }
                //调用姜宇，清空redis中报警设置
                ModelMap result = HttpUtils.HttpUtils_RequestGet(cleanAlarmSettingUrl, "");
                System.out.println(result);
                return R.ok( null,"绑定成功");
            }
            return R.failed(null,"未找到该报警设置");
        }
        return R.failed(null,"报警设置id不能为空");
    }
    @ApiOperation(value = "报警设置解除绑定传感器")
    @PostMapping("/alarmSettingDeleteSensor")
    public R alarmSettingDeleteSensor(@RequestBody AlarmSettingBindDto alarmSettingBindDto){
        if(alarmSettingBindDto.getAlarmSettingId() != null){
            String alarmSettingId = alarmSettingBindDto.getAlarmSettingId();
            long count = alarmSettingService.count(Wrappers.<AlarmSetting>query().lambda().eq(AlarmSetting::getAlarmId,alarmSettingId));
            if(count != 0) {
                String[] ids = alarmSettingBindDto.getSensorIds();
                for(String id : ids){
                    List<AlarmSensor> list = alarmSensorService.list(Wrappers.<AlarmSensor>query().lambda().eq(AlarmSensor::getSensorid,id));
                    list.stream().forEach(alarmSensor -> {
                        alarmSensorService.removeById(alarmSensor.getId());
                    });
                }
                //调用姜宇，清空redis中报警设置
                ModelMap result = HttpUtils.HttpUtils_RequestGet(cleanAlarmSettingUrl, "");
                System.out.println(result);
                return R.ok( null,"解除绑定成功");
            }
            return R.failed(null,"未找到该报警设置");
        }
        return R.failed(null,"报警设置id不能为空");
    }

    @ApiOperation(value = "获取报警列表")
    @PostMapping("/queryAlarmList")
    public R queryAlarmList(@RequestBody AlarmListDto alarmListDto){
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        alarmListDto.setDeviceTableName(deviceTableName);
        alarmListDto.setMonitorTableName(monitorTableName);
        IPage<AlarmListVo> page = sensorCheckAlarmService.queryAlarmList(alarmListDto);
        return R.ok(page,"获取成功");
    }

    @ApiOperation(value = "导出报警列表")
    @PostMapping("/exportAlarmList")
    public R exportAlarmList(@RequestBody AlarmListDto alarmListDto,HttpServletResponse response){
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        alarmListDto.setDeviceTableName(deviceTableName);
        alarmListDto.setMonitorTableName(monitorTableName);
        List<AlarmListVo> list = sensorCheckAlarmService.exportAlarmList(alarmListDto);
        // 1.导出的header标题设置
        String[] headers = {"点位名称", "设备类型", "传感器类型", "报警类型", "报警等级", "报警值", "报警时间"
                , "传感器id", "报警开始时间", "报警状态", "工单状态", "工单编号", "上报类型"};
        // 2.导出header对应的字段设置
        Column[] columns = {
                Column.field("pointName"),
                Column.field("deviceType"),
                Column.field("sensorType"),
                Column.field("alarmType"),
                Column.field("alarmLevel"),
                Column.field("alarmValue"),
                Column.field("alarmTime"),
                Column.field("deviceSensorId"),
                Column.field("alarmStartTime"),
                Column.field("alarmStatus"),
                Column.field("orderStatus"),
                Column.field("orderNum"),
                Column.field("reportType")};
        ExcelUtils.export(response,"alarmList",list,ExportRules.simpleRule(columns, headers));
        return R.ok("导出成功");
    }

    @ApiOperation(value = "根据报警级别获取所有当前报警数据")
    @PostMapping("/allAlarmNowList")
    public R allAlarmNowList(@RequestBody LevelDto levelDto){
        AlarmOnTimeDto alarmOnTimeDto = new AlarmOnTimeDto();
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        alarmOnTimeDto.setDeviceTableName(deviceTableName);
        alarmOnTimeDto.setMonitorTableName(monitorTableName);
        alarmOnTimeDto.setAlarmLevel(levelDto.getLevel());
        List<AlarmOnTimeVo> list = sensorCheckAlarmService.alarmNowList(alarmOnTimeDto);
        return R.ok(list,"获取成功");
    }
    @ApiOperation(value = "发送报警数据给WebSocket")
    @PostMapping("/sendAlarmMessage")
    public R sendAlarmMessage(@RequestBody IdDto idDto) throws IOException {
        AlarmNowDto alarmNowDto = new AlarmNowDto();
        String monitorTableName = smregisterService.getTableName("MonitorPoint");
        String deviceTableName = smregisterService.getTableName("DevicePoint");
        alarmNowDto.setDeviceTableName(deviceTableName);
        alarmNowDto.setMonitorTableName(monitorTableName);
        alarmNowDto.setAlarmId(idDto.getId());
        AlarmListVo vo = sensorCheckAlarmService.alarmNowById(alarmNowDto);
        String info = JSON.toJSONString(vo);
        webSocketServer.sendInfo(info);
        return R.ok(info,"发送成功");
    }

    @ApiOperation(value = "报警信息绑定案件编号")
    @PostMapping("/bindCasenum")
    public R bindCasenum(@RequestBody CaseBindDto caseBindDto){
        if(caseBindDto.getId()!=null){
            long count = sensorCheckAlarmService.count(Wrappers.<SensorCheckAlarm>query().lambda().eq(SensorCheckAlarm::getAlarmId,caseBindDto.getId()));
            if(count != 0) {
                SensorCheckAlarm alarm = sensorCheckAlarmService.getById(caseBindDto.getId());
                alarm.setOrderStatus("1");
                alarm.setOrderNum(caseBindDto.getCasenum());
                return R.ok( sensorCheckAlarmService.updateById(alarm),"绑定成功");
            }
            return R.failed(null,"未找到该数据");
        }
        return R.failed(null,"id不能为空");
    }

}
